#pragma once
#include <unistd.h>
#include <cstdlib>
#include <cstdio>
#include <ctime>
#include <iostream>
#include <cstdio>
#include <stdarg.h>
#include <cassert>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define DEBUG 0
#define NOTICE 1
#define WARNNING 2
#define FATAL 3

const char *log_level[] = {"DEBUG", "NOTICE", "WARNNING", "FATAL"};

#define LOGFILE "serverTcp.log"
class Log 
{
public:
    Log():logFd(-1)
    {}
    void enable()
    {
        umask(0);
        logFd = open(LOGFILE, O_WRONLY | O_CREAT | O_APPEND, 0666);
        assert(logFd != -1);
        dup2(logFd, 1);
        dup2(logFd, 2);
    }
    ~Log()
    {
        if (logFd != -1)
        {
            syncfs(logFd);
            close(logFd);
        }
    }

private:
    int logFd;
};
void logMessage(int level, const char *format, ...)
{
    assert(level >= DEBUG);
    assert(level <= FATAL);
    char *name = getenv("USER");
    va_list ap;
    va_start(ap, format);
    char logInfo[1024];
    vsnprintf(logInfo, sizeof(logInfo) - 1, format, ap);
    va_end(ap);
    umask(0);
    // int fd = open(LOGFILE, O_WRONLY | O_CREAT | O_APPEND, 0666);
    // assert(fd >= 0);
    FILE *out = (level == FATAL) ? stderr : stdout;
    // dup2(fd, 1);
    // dup2(fd, 2);
    fprintf(out, "%s | %u | %s | %s\n", log_level[level],
            (unsigned int)time(nullptr), name == nullptr ? "unknow" : name, logInfo);
    fflush(out);
    //fsync(fd);
    //close(fd);
}